 /*
    Copyright (C) 2009 Modelon AB

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 3 as published
    by the Free Software Foundation, or optionally, under the terms of the
    Common Public License version 1.0 as published by IBM.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License, or the Common Public License, for more details.

    You should have received copies of the GNU General Public License
    and the Common Public License along with this program.  If not,
    see <http://www.gnu.org/licenses/> or
    <http://www.ibm.com/developerworks/library/os-cpl.html/> respectively.
*/

/** \file jmi.h
 *  \brief The public JMI model interface.
 **/

/** \mainpage The JModelica.org C runtime library
 *
 * The JModelica C runtime library contains functions and data structures for
 * accessing the C model representation that is generated by the JModelica
 * Modelica and Optimica front-ends, respectively. The library is organized into
 * two main parts.
 *
 *  \section fmi_model_interfance The Functional Mock-up interface
 *   The Functional Mock-up Interface (FMI) defines a standard for model exchange 
 *   with a small set of functions for model interaction while at the same time 
 *   provide the necessary means for simulation of complex hybrid dynamic models.
 *   - <a href="group__fmi__public.html"> Documentation of the public Functional
 *     Mock-up interface</a>
 *   - <a target="_parent" href="http://www.functional-mockup-interface.org/"> 
 *     The Functional Mock-up interface</a>
 *  \section jmi_model_interface The JMI Model interface
 *   The JMI Model interface interface contains functions
 *    for evaluating the function generated by the compiler, including the DAE residual, the
 *    residual functions for the DAE initialization problem, and the functions related to
 *    the optimization problem such as cost functions and constraint residual functions.
 *    The JMI Model interface also supports evaluation of symbolic Jacobians (if available)
 *    and/or Jacobians computed by means of automatic differentiation. Sparsity patterns for
 *    Jacobians are supported.
 *      - <a href="group__Jmi.html"> Documentation of the public JMI Model interface </a>
 *      - <a href="group__Jmi__internal.html"> Documentation of the internal JMI Model interface </a>
 *
 * \section limitations Limitations
 * The JModelica.org JMI interface is under development. The function signatures
 * are likely to change in the future - all feedback is very welcome. The following
 * limitations apply:
 *   - Symbolic Jacobians are not provided by the compiler. This is actually
 *   a limitation in the code generation module, but as a consequence, the
 *   JMI_DER_SYMBOLIC flag cannot be used in the JMI interface.
 *   - The ODE interface is very limited and requires a Modelica model to be
 *   stated on explicit ODE form (\f$\dot x=f(x,u)\f$) in order to work.
 *
 */

/**
 * \defgroup Jmi The JMI Model interface
 *
 * \brief Documentation of the public JMI Model interface.
 *
 *  \section DesignConsiderations Design considerations
 *
 * The JMI Model interface is intended to be used in a wide range of
 * applications and on multiple platforms. This also includes embedded
 * platforms in HILS applications.
 *
 * It is desirable that the JMI Model interface can be easily interfaced
 * with Python. Python is the intended language for scripting in JModelica and it is
 * therefore important that the generated code is straight forward to use with the
 * Python extensions or ctypes framework.
 *
 * The JMI Model interface is intended to be used by wide range of users,
 * with different backgrounds and programming skills. It is therefore desirable that
 * the interface is as simple and intuitive as possible.
 *
 * Given these motivations, it is reasonable to use pure C where possible, and to a
 * limited extent C++ where needed (e.g. in solver interfaces and in most likely in the
 * AD framework).
 *
 * It should also be possible to build shared libraries, in order to
 * build applications that contains several models.
 *
 *
 * \section MathDescr Mathematical description of the JMI Model interface
 *
 *   The jmi interface consists of three parts: DAE, DAE initialization and optimization.
 *   Essentially, the jmi interface consists of a collection of functions that are
 *   offered to the user for evaluation of the DAE residual, cost functions, constraints
 *   etc. These functions takes as arguments one more of the following three argument
 *   types:
 *
 *   Parameters (denoted \f$p\f$):
 *    - \f$c_i^r\f$   independent real constant
 *    - \f$c_d^r\f$   dependent real constants
 *    - \f$p_i^r\f$   independent real parameters
 *    - \f$p_d^r\f$   dependent real parameters
 *    - \f$c_i^i\f$   independent integer constant
 *    - \f$c_d^i\f$   dependent integer constants
 *    - \f$p_i^i\f$   independent integer parameters
 *    - \f$p_d^i\f$   dependent integer parameters
 *    - \f$c_i^b\f$   independent boolean constant
 *    - \f$c_d^b\f$   dependent boolean constants
 *    - \f$p_i^b\f$   independent boolean parameters
 *    - \f$p_d^b\f$   dependent boolean parameters
 *
 *    with
 *
 *      \f$ p = [{c_i^r}^T, {c_d^r}^T, {p_i^r}^T, {p_d^r}^T, {c_i^i}^T, {c_d^i}^T, {p_i^i}^T, {p_d^i}^T, {c_i^b}^T, {c_d^b}^T, {p_i^b}^T, {p_d^b}^T]^T \f$
 *
 *   Variables (denoted \f$v\f$):
 *
 *    - \f$\dot x\f$    differentiated real variables
 *    - \f$x\f$     real variables that appear differentiated
 *    - \f$u\f$     real inputs
 *    - \f$w\f$     real algebraic variables
 *    - \f$t\f$     time
 *
 *    with
 *
 *    \f$v = [\dot x^T, x^T, u^T, w^T, t]^T\f$
 *
 *   Variables defined at particular time instants (denoted \f$q\f$):
 *
 *      - \f$\dot x(t_i)\f$    differentiated real variables evaluated at time \f$t_i, i \in 1..n_{tp}\f$
 *      - \f$x(t_i)\f$     real variables that appear differentiated evaluated at time \f$t_i, t_i \in 1..n_{tp}\f$
 *      - \f$u(t_i)\f$     real inputs evaluated at time \f$t_i, i \in 1..n_{tp}\f$
 *      - \f$w(t_i)\f$     real algebraic variables evaluated at time \f$t_i, i \in 1..n_{tp}\f$
 *
 *    \f$ q = [\dot x(t_1)^T, x(t_1)^T, u(t_1)^T, w(t_1)^T, ...,
 *           \dot x(t_{n_{tp}})^T, x(t_{n_{tp}})^T, u(t_{n_{tp}})^T, w(t_{n_{tp}})^T]^T\f$
 *
 *   Discrete variables which may only change during events (denoted \f$d\f$);
 *
 *      -  \f$d^r\f$  discrete real variables
 *      -  \f$d^i\f$  integer variables
 *      -  \f$u^i\f$  integer inputs
 *      -  \f$d^b\f$  boolean variables
 *      -  \f$u^b\f$  boolean inputs
 *      -  \f$s\f$  boolean switches mapped from relational expressions Notice that these boolean variables
 *      do not originate from boolean variable declarations, but from boolean valued expressions such as
 *      x>=3.
 *
 *    \f$ d = [{d^r}^T, {d^i}^T, {u^i}^T, {d^b}^T, {d^b}^T,s]^T\f$
 *
 *   All parameters, variables, point-wise evaluated variables and discrete variables are denoted z:
 *
 *     \f$ z = [p^T, v^T, q^T, d^T]^T \f$
 *
 *   \subsection DAE The DAE interface
 *
 *   The DAE interface is defined by the residual function \f$F(p,v,d)\f$ where
 *
 *     \f$ F(p,v,d) = 0 \f$
 *
 *  For details on the functions included in the DAE interface, see the <a href="group__DAE.html">DAE functions documentation. </a>
 *
 *    \subsection Init The DAE initialization interface
 *
 *   The DAE initialization interface is defined by the functions \f$F_0(p,v)\f$ and \f$F_1(p,v)\f$ where
 *
 *    \f$  F_0(p,v,d) = 0 \f$<br>
 *    \f$  F_1(p,v,d) = 0 \f$
 *
 *   \f$F_0\f$ represents the DAE system augmented with additional initial equations
 *   and start values that are fixed. \f$F_1\f$ on the other hand contains equations for
 *   initialization of variables for which the value given in the start attribute is
 *   not fixed.
 *
 *   In addition, a residual function for dependent parameters is provided
 *
 *    \f$  F_p(p) = 0 \f$
 *
 *   The iteration variables of this system are the elements in the \f$p_d^r\f$,
 *   \f$p_d^i\f$, \f$p_d^b\f$ vectors.
 *
 *   For details on the functions included in the DAE initialization interface, see the
 *   <a href="group__Initialization.html">DAE initialization functions documentation. </a>
 *
 *   \subsection Ode_interface The ODE interface
 *
 *   The ODE interace is defined by the relation
 *
 *   \f$\dot x = f(p,x,u,t,d). \f$
 *
 *   WARNING: The current version of the JMI interface supports only Modelica
 *   models which are written explicitly on ODE form. Accordingly, no
 *   algebraic variables are supported in this version.
 *
 *  \section Jacobians Evaluation of Jacobians
 *
 *  Evaluation of Jacobians is controlled by four arguments:
 *
 *   - eval_alg    This argument is used to select the method evaluation
 *                     for the Jacobian. JMI_DER_SYMBOLIC and JMI_DER_CPPAD
 *                     is currently supported.
 *   - sparsity          This argument is a mask that selects whether
 *                     sparse or dense evaluation of the Jacobian should
 *                     be used. The constants JMI_DER_SPARSE are used to
 *                     specify a sparse Jacobian, whereas JMI_DER_DENSE_COL_MAJOR
 *                     and JMI_DER_DENSE_ROW_MAJOR are used to specify dense
 *                     column major or row major Jacobians respectively.
 *   - independent_vars  This argument is used to specify which variable types
 *                     are considered to be independent variables in the Jacobian
 *                     evaluation. The constants JMI_DER_NN are used to indicate that
 *                     the Jacobian w.r.t. a particular vector should be evaluated.
 *   - mask              This array has the same size as the number of column of the dense
 *                     Jacobian (equal to the size of the vector \f$z\f$), and holds the value of 0 if the corresponding Jacobian
 *                     column should not be computed. If the value of an entry in
 *                     mask i 1, then the corresponding Jacobian column will be evaluated.
 *                     The evaluated Jacobian columns are stored in the first
 *                     entries of the output argument jac.
 *
 *  Notice that only Jacobian evaluation w.r.t. real parameters and variables
 *  is currently supported.
 *
 *  TODO: It may be interesting to include an additional layer that enables
 *  support for partially defined Jacobians. This would be beneficial if symbolic
 *  expressions for the Jacobian is available for some entries, but for other
 *  an AD algorithm is to be used.
 *
 * \section ErrorHandling Error handling
 */

#ifndef _JMI_H
#define _JMI_H

#include "jmi_util.h"
#include "jmi_global.h"
#include "jmi_block_solver.h"


/* @{ */

/**
 * \defgroup Defines Defined constants
 * \brief Constants defined in the JMI Model interface.
 */
/* @{ */

#define JMI_INF 1e20                /**< \brief A Very Large Number denoting infinity.*/
#define JMI_SMALL 1e-6              /**< \brief A Quite Small Number. */

/*The option JMI_DER_CPPAD is no longer used and should be removed.*/
#define JMI_DER_SYMBOLIC 1          /**< \brief Use symbolic evaluation of derivatives (if available). */
#define JMI_DER_CPPAD 2             /**< \brief Use automatic differentiation (CppAD) to evaluate derivatives. */
#define JMI_DER_CAD 4               /**< \brief Use automatic differentiation (generated C code) to evaluate derivatives. */
#define JMI_DER_FD 8                /**< \brief Use finite differences to evaluate derivatives. */

#define JMI_DER_CHECK_SCREEN_ON 1   /**< \brief Prints all evaluation errors on the screen, returns 0. */
#define JMI_DER_CHECK_SCREEN_OFF 2  /**< \brief Return -1 if an evaluation error occur. */

#define JMI_DER_SPARSE 1            /**< \brief Sparse evaluation of derivatives. */
#define JMI_DER_DENSE_COL_MAJOR 2   /**<  \brief Dense evaluation (column major) of derivatives. */
#define JMI_DER_DENSE_ROW_MAJOR 4   /**<  \brief Dense evaluation (row major) of derivatives. */

/* Flags for evaluation of Jacobians w.r.t. parameters in the p vector */
#define JMI_DER_P_OPT 8192          /**< \brief Evaluate derivatives w.r.t. real free parameters, \f$p_{opt}\f$.*/
#define JMI_DER_CI 1                /**< \brief Evaluate derivatives w.r.t. real independent constants, \f$c_i\f$.*/
#define JMI_DER_CD 2                /**< \brief Evaluate derivatives w.r.t. real dependent constants, \f$c_d\f$.*/
#define JMI_DER_PI 4                /**< \brief Evaluate derivatives w.r.t. real independent parameters, \f$p_i\f$.*/
#define JMI_DER_PD 8                /**< \brief Evaluate derivatives w.r.t. real dependent constants, \f$p_d\f$.*/
/* Flags for evaluation of Jacobians w.r.t. variables in the v vector */
#define JMI_DER_DX 16               /**< \brief Evaluate derivatives w.r.t. real derivatives, \f$\dot x\f$.*/
#define JMI_DER_X 32                /**< \brief Evaluate derivatives w.r.t. real differentiated variables, \f$x\f$.*/
#define JMI_DER_U 64                /**< \brief Evaluate derivatives w.r.t. real inputs, \f$u\f$.*/
#define JMI_DER_W 128               /**< \brief Evaluate derivatives w.r.t. real algebraic variables, \f$w\f$.*/
#define JMI_DER_T 256               /**< \brief Evaluate derivatives w.r.t. real time, \f$t\f$.*/

/** \brief Evaluate derivatives w.r.t. all variables, \f$z\f$.*/
#define JMI_DER_ALL (JMI_DER_CI | JMI_DER_CD | JMI_DER_PI | JMI_DER_PD |\
    JMI_DER_DX | JMI_DER_X | JMI_DER_U | JMI_DER_W | JMI_DER_T  )

/**  \brief Evaluate derivatives w.r.t. all variables in \f$p\f$.*/
#define JMI_DER_ALL_P JMI_DER_CI | JMI_DER_CD | JMI_DER_PI | JMI_DER_PD

/**  \brief Evaluate derivatives w.r.t. all variables in \f$v\f$.*/
#define JMI_DER_ALL_V JMI_DER_DX | JMI_DER_X | JMI_DER_U | JMI_DER_W |\
    JMI_DER_T

/**  \brief Definitions of boolean true and false literals.*/
#define JMI_TRUE  ((jmi_real_t) (1.0))
#define JMI_FALSE ((jmi_real_t) (0.0))

/** \brief */
#define JMI_SCALING_NONE 1        /**< \brief No scaling.*/
#define JMI_SCALING_VARIABLES 2   /**< \brief Scale real variables by multiplying incoming variables in residual functions by the scaling factors in jmi_t->variable_scaling_factors */

#define JMI_REL_GT 0
#define JMI_REL_GEQ 2
#define JMI_REL_LT 4
#define JMI_REL_LEQ 8

#define JMI_ODE_OK 0
#define JMI_ODE_EVENT 1
#define JMI_ODE_ERROR -1

 typedef enum {
     JMI_ODE_CVODE,
     JMI_ODE_EULER
 } jmi_ode_method_t;

/* @} */

/*
 *****************************************
 *
 *    Public interface
 *
 ****************************************
 */

/**
 * \defgroup jmi_struct Creation, initialization and destruction of jmi_t structs
 * \brief The main data structure in the JMI Model interface is jmi_t, which contains
 * all information needed to evaluate the functions in the JMI Model interface.
 *
 * Typically,
 * a pointer to a jmi_t struct is passed as the first argument to functions in the interface.
 *
 *
 */

/* @{ */

/**
 * \brief Create a new jmi_t struct.
 *
 * This function creates a new jmi struct, for which a pointer is returned in the output argument jmi.
 *
 * Typically this function is defined in the generated code.
 *
 * @param jmi A pointer to a jmi_t pointer where the new jmi_t struct is stored.
 * @param jmi_callbacks A jmi_callbacks_t struct.
 * @return Error code.
 */
int jmi_new(jmi_t** jmi, jmi_callbacks_t* jmi_callbacks);

/**
 * Clean up after a completed simulation.
 *
 * @param jmi A pointer to the jmi_t struct to clean up.
 * @return Error code.
 */
int jmi_terminate(jmi_t* jmi);

/**
 * Deallocates memory and deletes a jmi_t struct.
 *
 * @param jmi A pointer to the jmi_t struc to be deleted.
 */
int jmi_delete(jmi_t* jmi);

/* @} */

/**
 * \defgroup Access Setters and getters for the fields in jmi_t
 *
 * \brief The fields of jmi_t are conveniently accessed using the setter and getter
 * functions provided in the JMI Model interface.
 *
 * Notice that it is not recommended to access the fields directely, since the internal
 * implementation of jmi_t may change, wheras the setters and getters are less likely to
 * do so.
 *
 */

/* @{ */

/**
 * \brief Get the sizes of the variable vectors.
 *
 * @param jmi The jmi_t struct.
 * @param n_real_ci (Output) number of real independent constants.
 * @param n_real_cd (Output) number of real dependent constants.
 * @param n_real_pi (Output) number of real independent parameters.
 * @param n_real_pd (Output) number of real dependent parameters.
 * @param n_integer_ci (Output) number of integer independent constants.
 * @param n_integer_cd (Output) number of integer dependent constants.
 * @param n_integer_pi (Output) number of integer independent parameters.
 * @param n_integer_pd (Output) number of integer dependent parameters.
 * @param n_boolean_ci (Output) number of boolean independent constants.
 * @param n_boolean_cd (Output) number of boolean dependent constants.
 * @param n_boolean_pi (Output) number of boolean independent parameters.
 * @param n_boolean_pd (Output) number of boolean dependent parameters.
 * @param n_real_dx (Output) number of real derivatives.
 * @param n_real_x (Output) number of real differentiated variables.
 * @param n_real_u (Output) number of real inputs.
 * @param n_real_w (Output) number of real algebraic variables.
 * @param n_real_d (Output) number of real discrete variables.
 * @param n_integer_d (Output) number of integer discrete variables.
 * @param n_integer_u (Output) number of integer inputs.
 * @param n_boolean_d (Output) number of boolean discrete variables.
 * @param n_boolean_u (Output) number of boolean inputs.
 * @param n_outputs (Output) number of outputs.
 * @param n_sw (output) number of switching functions in the DAE \f$F\f$.
 * @param n_sw_init (output) number of switching functions in the initialization system \f$F_0\f$.
 * @param n_guards (output) number of guards in the DAE \f$F\f$.
 * @param n_guards_init (output) number of guards in the initialization system \f$F_0\f$.
 * @param n_z (Output) total number of variables in the \f$z\f$ vector.
 * @return Error code.
 *
 */
int jmi_get_sizes(jmi_t* jmi, int* n_real_ci, int* n_real_cd, int* n_real_pi, int* n_real_pd,
        int* n_integer_ci, int* n_integer_cd, int* n_integer_pi, int* n_integer_pd,
        int* n_boolean_ci, int* n_boolean_cd, int* n_boolean_pi, int* n_boolean_pd,
        int* n_real_dx, int* n_real_x, int* n_real_u, int* n_real_w, int* n_real_d, 
        int* n_integer_d, int* n_integer_u, int* n_boolean_d, int* n_boolean_u,
        int* n_outputs, int* n_sw, int* n_sw_init, int* n_guards, int* n_guards_init, int* n_z);

/**
 * \brief Get the offsets for the variable types in the \f$z\f$ vector.
 *
 * @param jmi The jmi_t struct.
 * @param offs_real_ci (Output) offset of real independent constants.
 * @param offs_real_cd (Output) offset of real dependent constants.
 * @param offs_real_pi (Output) offset of real independent parameters.
 * @param offs_real_pd (Output) offset of real dependent parameters.
 * @param offs_integer_ci (Output) offset of integer independent constants.
 * @param offs_integer_cd (Output) offset of integer dependent constants.
 * @param offs_integer_pi (Output) offset of integer independent parameters.
 * @param offs_integer_pd (Output) offset of integer dependent parameters.
 * @param offs_boolean_ci (Output) offset of boolean independent constants.
 * @param offs_boolean_cd (Output) offset of boolean dependent constants.
 * @param offs_boolean_pi (Output) offset of boolean independent parameters.
 * @param offs_boolean_pd (Output) offset of boolean dependent parameters.
 * @param offs_real_dx (Output) offset of real derivatives.
 * @param offs_real_x (Output) offset of real differentiated variables.
 * @param offs_real_u (Output) offset of real inputs.
 * @param offs_real_w (Output) offset of real algebraic variables.
 * @param offs_t (Output) offset of time.
 * @param offs_real_d (Output) offset of real discrete variables.
 * @param offs_integer_d (Output) offset of integer discrete variables.
 * @param offs_integer_u (Output) offset of integer input variables.
 * @param offs_boolean_d (Output) offset of boolean discrete variables.
 * @param offs_boolean_u (Output) offset of boolean input variables.
 * @param offs_sw (Output) offset of the first switching function in the DAE \f$F_0\f$.
 * @param offs_sw_init (Output) offset of the first switching function in the initialization system \f$F_0\f$.
 * @param offs_guards (Output) offset of the first guard in the DAE \f$F_0\f$.
 * @param offs_guards_init (Output) offset of the first pre in the initialization system \f$F_0\f$.
 * @param offs_pre_real_dx (Output) offset of pre real derivatives.
 * @param offs_pre_real_x (Output) offset of pre real differentiated variables.
 * @param offs_pre_real_u (Output) offset of pre real inputs.
 * @param offs_pre_real_w (Output) offset of pre real algebraic variables.
 * @param offs_pre_real_d (Output) offset of pre real discrete variables.
 * @param offs_pre_integer_d (Output) offset pre of integer discrete variables.
 * @param offs_pre_integer_u (Output) offset pre of integer input variables.
 * @param offs_pre_boolean_d (Output) offset pre of boolean discrete variables.
 * @param offs_pre_boolean_u (Output) offset pre of boolean input variables.
 * @param offs_pre_sw (Output) offset of the first pre switching function in the DAE \f$F_0\f$.
 * @param offs_pre_sw_init (Output) offset of the first pre switching function in the initialization system \f$F_0\f$.
 * @param offs_pre_guards (Output) offset of the first pre guard in the DAE \f$F_0\f$.
 * @param offs_pre_guards_init (Output) offset of the first pre guard in the initialization system \f$F_0\f$.
 * @return Error code.
 */
int jmi_get_offsets(jmi_t* jmi, int* offs_real_ci, int* offs_real_cd,
        int* offs_real_pi, int* offs_real_pd,
        int* offs_integer_ci, int* offs_integer_cd,
        int* offs_integer_pi, int* offs_integer_pd,
        int* offs_boolean_ci, int* offs_boolean_cd,
        int* offs_boolean_pi, int* offs_boolean_pd,
        int* offs_real_dx, int* offs_real_x, int* offs_real_u,
        int* offs_real_w, int *offs_t,
        int* offs_real_d, int* offs_integer_d, int* offs_integer_u,
        int* offs_boolean_d, int* offs_boolean_u,
        int* offs_sw, int* offs_sw_init,
        int* offs_guards_sw, int* offs_guards_init,
        int* offs_pre_real_dx, int* offs_pre_real_x, int* offs_pre_real_u,
        int* offs_pre_real_w,
        int* offs_pre_real_d, int* offs_pre_integer_d, int* offs_pre_integer_u,
        int* offs_pre_boolean_d, int* offs_pre_boolean_u,
        int* offs_pre_sw, int* offs_pre_sw_init,
        int* offs_pre_guards_sw, int* offs_pre_guards_init);

/**
 * \brief Copy variable values to the pre vector.
 *
 * @param jmi The jmi_t struct.
 * @return Error code.
 */
int jmi_copy_pre_values(jmi_t *jmi);

/**
 * \brief Reset the z vector to the last successful state.
 *
 * @param jmi The jmi_t struct.
 * @return Error code.
 */
int jmi_reset_last_successful_values(jmi_t *jmi);

/**
 * \brief Save the complete z vector.
 *
 * @param jmi The jmi_t struct.
 * @return Error code.
 */
int jmi_save_last_successful_values(jmi_t *jmi);

/**
 * \brief Get a pointer to the z vector containing all variables.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$z\f$ vector.
 *
 */
jmi_real_t* jmi_get_z(jmi_t* jmi);

/**
 * \brief Get a pointer to the last successful z vector containing all variables.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$z\f$ vector.
 *
 */
jmi_real_t* jmi_get_z_last(jmi_t* jmi);

/**
 * \brief Get a pointer to the real independent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_i^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_ci(jmi_t* jmi);

/**
 * \brief Get a pointer to the real dependent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_d^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_cd(jmi_t* jmi);

/**
 * \brief Get a pointer to the real independent parameter vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_i^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_pi(jmi_t* jmi);

/**
 * \brief Get a pointer to the real dependent parameters vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_d^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_pd(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer independent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_i^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_ci(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer dependent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_cd(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer independent parameter vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_i^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_pi(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer dependent parameters vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_pd(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean independent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_i^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_ci(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean dependent constants vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$c_d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_cd(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean independent parameter vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_i^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_pi(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean dependent parameters vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$p_d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_pd(jmi_t* jmi);

/**
 * \brief Get a pointer to the real derivatives vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$dx\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_dx(jmi_t* jmi);

/**
 * \brief Get a pointer to the differentiated variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$x\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_x(jmi_t* jmi);

/**
 * \brief Get a pointer to the inputs vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$u\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_u(jmi_t* jmi);

/**
 * \brief Get a pointer to the algebraic variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$w\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_w(jmi_t* jmi);

/**
 * \brief Get a pointer to the time value.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to \f$t\f$.
 *
 */
jmi_real_t* jmi_get_t(jmi_t* jmi);

/**
 * \brief Get a pointer to the derivatives corresponding to the i:th time point.
 *
 * @param jmi The jmi_t struct.
 * @param i Index of the time point: 0 corresponds to first time point.
 * @return A pointer to the \f$dx_{p,i}\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_dx_p(jmi_t* jmi,int i);

/**
 * \brief Get a pointer to the differentiated variables corresponding to the i:th time point.
 *
 * @param jmi The jmi_t struct.
 * @param i Index of the time point: 0 corresponds to first time point.
 * @return A pointer to the \f$x_{p,i}\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_x_p(jmi_t* jmi, int i);

/**
 * \brief Get a pointer to the inputs corresponding to the i:th time point.
 *
 * @param jmi The jmi_t struct.
 * @param i Index of the time point: 0 corresponds to first time point.
 * @return A pointer to the \f$u_{p,i}\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_u_p(jmi_t* jmi, int i);

/**
 * \brief Get a pointer to the algebraic variables corresponding to the i:th time point.
 *
 * @param jmi The jmi_t struct.
 * @param i Index of the time point: 0 corresponds to first time point.
 * @return A pointer to the \f$w_{p,i}\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_w_p(jmi_t* jmi, int i);

/**
 * \brief Get a pointer to the real discrete variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$d^r\f$ vector.
 *
 */
jmi_real_t* jmi_get_real_d(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer discrete variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_d(jmi_t* jmi);

/**
 * \brief Get a pointer to the integer input variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$u^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_integer_u(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean discrete variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$d^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_d(jmi_t* jmi);

/**
 * \brief Get a pointer to the boolean input variables vector.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the \f$u^i\f$ vector.
 *
 */
jmi_real_t* jmi_get_boolean_u(jmi_t* jmi);

/**
 * \brief Get the value references of the outputs.
 *
 * @param jmi A jmi_t struct.
 * @param output_vrefs (Output) An array containing the value references
 *                              of the outputs.
 * @return Error code.
 *
 */
int jmi_get_output_vrefs(jmi_t *jmi, int *output_vrefs);

/**
 * \brief Get a pointer to the first switching function in the DAE \$fF\$f.
 * A switch value of 1 corresponds to true and 0 corresponds to false.
 *
 * @param jmi The jmi_t struct.
 * @return A pointer to the vector of switching functions.
 *
 */
jmi_real_t* jmi_get_sw(jmi_t* jmi);

/**
 * \brief Get a pointer to the first switching function in the initialization system \$fF_0\$f.
 * A switch value of 1 corresponds to true and 0 corresponds to false.
 * @param jmi The jmi_t struct.
 * @return A pointer to the vector of switching functions.
 *
 */
jmi_real_t* jmi_get_sw_init(jmi_t* jmi);

/**
 * \brief Get a pointer to the scaling factor vector.
 * @param jmi The jmi_t struct.
 * @return A pointer to the scaling factor vector.
 *
 */
jmi_real_t* jmi_get_variable_scaling_factors(jmi_t* jmi);

/**
 * \brief Get the scaling method. Alternatives are JMI_SCALING_NONE and
 * JMI_SCALING_VARIABLES.
 * @param jmi The jmi_t struct.
 * @return An integer representing the scaling method used.
 *
 */
int jmi_get_scaling_method(jmi_t* jmi);


/**
 * \brief Get the name of the model that produced this FMU/JMU.
 */
const char *jmi_get_model_identifier();


/* @} */


/*********************************************
 *
 * ODE interface
 *
 ********************************************/

/**
 * \defgroup ODE ODE interface
 * \brief Access to the ODE representation.
 *
 * WARNING: The current version of the ODE interface is very limited and
 * requires that the Modelica model is explicitly given on ODE form.
 * Accordingly, algebraic variables are not supported.
 */
/* @{ */


/**
 * \brief Evaluate the right hand side of the ODE.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_x, ::jmi_get_u etc. The
 * output (the values of the derivatives) is available after a call to
 * ::jmi_ode_f in the vector obtained by calling ::jmi_get_dx.
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 *
 */
int jmi_ode_f(jmi_t* jmi);

/**
 * \brief Evaluate the Jacobian of the right hand side of the ODE.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_x, ::jmi_get_u etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
 *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
 * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
 *                to indicate the output format of the Jacobian.
 * @param independent_vars Used to indicate which columns of the full Jacobian should
 *                         be evaluated. The constants JMI_DER_X, JMI_DER_DX etc are used
 *                         to set this argument. Setting independent_vars to
 *                         JMI_DER_DX has no effect.
 * @param mask This argument is a vector containing ones for the Jacobian columns that
 *             should be included in the Jacobian and zeros for those which should not.
 *             The size of this vector is the same as the z vector.
 * @param jac (Output) The Jacobian.
 * @return Error code.
 *
 */
int jmi_ode_df(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);

/**
 * \brief Returns the number of non-zeros in the Jacobian of the right hand
 * side of the ODE.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
 *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
 * @param n_nz (Output) The number of non-zero Jacobian entries.
 * @return Error code.
 */
int jmi_ode_df_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);

/**
 * \brief Returns the row and column indices of the non-zero elements in the
 * Jacobian of the right hand side.
 *
 * Notice that Fortran style indexing is used: the first row (and column) has index 1.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param row (Output) The row indices of the non-zeros in the Jacobian.
 * @param col (Output) The column indices of the non-zeros in the Jacobian.
 * @return Error code.
 *
 */
int jmi_ode_df_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
                          int *mask, int* row, int* col);

/**
 * \brief This helper function computes the number of columns and the number of non zero
 * elements in the Jacobian of the right hand side of the ODE given a sparsity configuration.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param df_n_cols (Output) The number of columns of the resulting Jacobian.
 * @param df_n_nz (Output) The number of non-zeros of the resulting Jacobian.
 *
 */
int jmi_ode_df_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
        int *df_n_cols, int *df_n_nz);

/**
 * \brief Evaluate the ODE derivatives.
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_ode_derivatives(jmi_t* jmi);

/**
 * \brief Evaluate the ODE directional derivatives.
 *
 * @param jmi A jmi_t struct.
 * @param dv The seed vector.
 * @return Error code.
 */
int jmi_ode_derivatives_dir_der(jmi_t* jmi, jmi_real_t* dv);

/**
 * \brief Evaluate the ODE outputs.
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_ode_outputs(jmi_t* jmi);

/**
 * \brief Initialize the ODE.
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_ode_initialize(jmi_t* jmi);

/**
 * \brief Evaluate the DAE guard expressions
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_ode_guards(jmi_t* jmi);

/**
 * \brief Evaluate the initial equation guard expressions
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_ode_guards_init(jmi_t* jmi);

/**
 * \brief Computes the next time event.
 *
 * @param jmi A jmi_t struct.
 * @param nextTime (Output) The time instant of the next time event.
 * @return Error code.
 */
int jmi_ode_next_time_event(jmi_t* jmi, jmi_real_t* nextTime);


/* @} */

/*********************************************
 *
 * DAE interface
 *
 ********************************************/

/**
 * \defgroup DAE DAE interface
 * \brief Access to the DAE residual function.
 *
 */
/* @{ */


/**
 * \brief Get the number of equations of the DAE and the number of event
 * indicator residuals.
 *
 * @param jmi A jmi_t struct.
 * @param n_eq_F (Output) The number of DAE equations is stored in this
 * argument.
 * @param n_eq_R (Output) The number of DAE event indicator residuals is
 * stored in this argument.
 * @return Error code.
 */
int jmi_dae_get_sizes(jmi_t* jmi, int* n_eq_F, int* n_eq_R);


/**
 * \brief Evaluate DAE residual.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param res (Output) The DAE residual vector.
 * @return Error code.
 *
 */
int jmi_dae_F(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Evaluate the Jacobian of the DAE residual function.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
 *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
 * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
 *                to indicate the output format of the Jacobian.
 * @param independent_vars Used to indicate which columns of the full Jacobian should
 *                         be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used
 *                         to set this argument.
 * @param mask This argument is a vector containing ones for the Jacobian columns that
 *             should be included in the Jacobian and zeros for those which should not.
 *             The size of this vector is the same as the z vector.
 * @param jac (Output) The Jacobian.
 * @return Error code.
 *
 */
int jmi_dae_dF(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);

/**
 * \brief Returns the number of non-zeros in the full DAE residual Jacobian.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg Indicates which for which Jacobian the number of non-zero elements should be returned:
 *                 Symbolic (JMI_DER_SYMBOLIC), CAD (JMI_DER_CAD) or finite differences (JMI_DER_FD).
 * @param n_nz (Output) The number of non-zero Jacobian entries.
 * @return Error code.
 */
int jmi_dae_dF_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);

/**
 * \brief Returns the row and column indices of the non-zero elements in the DAE
 * residual Jacobian.
 *
 * Notice that Fortran style indexing is used: the first row (and column) has index 1.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param row (Output) The row indices of the non-zeros in the DAE residual Jacobian.
 * @param col (Output) The column indices of the non-zeros in the DAE residual Jacobian.
 * @return Error code.
 *
 */
int jmi_dae_dF_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
                          int *mask, int* row, int* col);

/**
 * \brief This helper function computes the number of columns and the number of non zero
 * elements in the Jacobian of the DAE residual given a sparsity configuration.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
 * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
 *
 */
int jmi_dae_dF_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
        int *dF_n_cols, int *dF_n_nz);

/**
 * \brief Evaluate the directional derivative of the DAE residual function.
 *
 * The directional derivative is defined as
 *
 *   dF = dF/dz * dz
 *
 * where dF/dz is the Jacobian of the residual function F, dF
 * is the directional derivative and dz is the seed vector.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg int
 * @param res (Output) The DAE residual vector.
 * @param dF (Output) The directional derivative.
 * @param dz Seed vector of size n_x + n_x + n_u + n_w.
 * @return Error code.
 *
 */
int jmi_dae_directional_dF(jmi_t* jmi, int eval_alg, jmi_real_t* res, jmi_real_t* dF, jmi_real_t* dz);

/**
 * \brief Evaluate DAE event indicator residuals.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param res (Output) The event indicator residuals.
 * @return Error code.
 *
 */
int jmi_dae_R(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Evaluate the adjusted DAE event indicator residuals.
 *
 * This method perturbes the event indicator functions based on the
 * relation operator (>,>=,<,<=) and the current value of the event
 * indicator with an epsilon (jmi->events_epsilon)
 *
 * @param jmi A jmi_t struct.
 * @param res (Output) The event indicator residuals.
 * @return Error code.
 *
 */
int jmi_dae_R_perturbed(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Compare the evaluated CAD derivative with the FD evaluation
 *
 * @param jmi A jmi_t struct.
 * @param sparsity Set to JMI_DER_SPARSE, JMI_DER_DENSE_COL_MAJOR, or JMI_DER_DENS_ROW_MAJOR
 *                to indicate the output format of the Jacobian.
 * @param independent_vars Used to indicate which columns of the full Jacobian should
 *                         be evaluated. The constants JMI_DER_DX, JMI_DER_X etc are used
 *                         to set this argument.
 * @param screen_use Set the flag to JMI_DER_CHECK_SCREEN_ON to print the result of the comparasion on the screen
 *             or JMI_DER_CHECK_SCREEN_OFF to return -1 if the comparasion failes. 
 * @param mask This argument is a vector containing ones for the Jacobian columns that
 *             should be included in the Jacobian and zeros for those which should not.
 *             The size of this vector is the same as the z vector.
 * @return Error code.
 *
 */
int jmi_dae_derivative_checker(jmi_t* jmi, int sparsity, int independent_vars, int screen_use, int *mask);

/* @} */

/*********************************************
 *
 * Initialization interface
 *
 ********************************************/

/**
 * \defgroup Initialization DAE Initialization Interface
 * \brief Access to the DAE initialization functions.
 */
/* @{ */

/**
 * \brief Get the number of equations in the DAE initialization functions.
 *
 * @param jmi A jmi_t struct.
 * @param n_eq_F0 (Output) The number of equations in \f$F_0\f$ is stored in this argument.
 * @param n_eq_F1 (Output) The number of equations in \f$F_1\f$ is stored in this argument.
 * @param n_eq_Fp (Output) The number of equations in \f$F_p\f$ is stored in this argument.
 * @param n_eq_R0 (Output) The number of equations in \f$R_0\f$ is stored in this argument.
 * @return Error code.
 *
 */
int jmi_init_get_sizes(jmi_t* jmi, int* n_eq_F0, int* n_eq_F1, int* n_eq_Fp,
        int* n_eq_R0);

/**
 * \brief Evaluate the \f$F_0\f$ residual function of the initialization system.
 *
 * @param jmi A jmi_t struct.
 * @param res The residual of \f$F_0\f$.
 * @return Error code.
 */
int jmi_init_F0(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_0\f$.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param jac (Output) The Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dF0(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);

/**
 * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_0\f$.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF_n_nz.
 * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
 * @return Error code.
 */
int jmi_init_dF0_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);

/**
 * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
 * initialization residual function \f$F_0\f$.
 *
 * Notice that Fortran style indexing is used: the first row (and column) has index 1.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param row (Output) The row indices of the non-zeros in the Jacobian.
 * @param col (Output) The column indices of the non-zeros in the Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dF0_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
        int *mask, int* row, int* col);

/**
 * \brief This helper function computes the number of columns and the number of non-zero
 * elements in the Jacobian of the DAE initialization residual function \f$F_0\f$ given
 * a sparsity configuration.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
 * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
 *
 */
int jmi_init_dF0_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
        int *dF_n_cols, int *dF_n_nz);

/**
 * \brief Evaluate the \f$F_1\f$ residual function of the initialization system.
 *
 * @param jmi A jmi_t struct.
 * @param res The residual of \f$F_1\f$.
 * @return Error code.
 */
int jmi_init_F1(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_1\f$.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param jac (Output) The Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dF1(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);

/**
 * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_1\f$.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF_n_nz.
 * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
 * @return Error code.
 */
int jmi_init_dF1_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);

/**
 * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
 * initialization residual function \f$F_1\f$.
 *
 * Notice that Fortran style indexing is used: the first row (and column) has index 1.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param row (Output) The row indices of the non-zeros in the Jacobian.
 * @param col (Output) The column indices of the non-zeros in the Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dF1_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
        int *mask, int* row, int* col);

/**
 * \brief This helper function computes the number of columns and the number of non-zero
 * elements in the Jacobian of the DAE initialization residual function \f$F_1\f$ given
 * a sparsity configuration.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
 * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
 *
 */
int jmi_init_dF1_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
        int *dF_n_cols, int *dF_n_nz);

/**
 * \brief Evaluate the \f$F_p\f$ residual function of the initialization system.
 *
 * @param jmi A jmi_t struct.
 * @param res The residual of \f$F_p\f$.
 * @return Error code.
 */
int jmi_init_Fp(jmi_t* jmi, jmi_real_t* res);

/**
 * \brief Evaluate the Jacobian of the DAE initialization residual function \f$F_p\f$.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param jac (Output) The Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dFp(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int* mask, jmi_real_t* jac);

/**
 * \brief Returns the number of non-zeros in the full Jacobian of the DAE initialization residual function \f$F_p\f$.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF_n_nz.
 * @param n_nz (Output) The number of non-zero entries in the full Jacobian.
 * @return Error code.
 */
int jmi_init_dFp_n_nz(jmi_t* jmi, int eval_alg, int* n_nz);

/**
 * \brief Returns the row and column indices of the non-zero elements in the Jacobain of the DAE
 * initialization residual function \f$F_p\f$.
 *
 * Notice that Fortran style indexing is used: the first row (and column) has index 1.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param row (Output) The row indices of the non-zeros in the Jacobian.
 * @param col (Output) The column indices of the non-zeros in the Jacobian.
 * @return Error code.
 *
 */
int jmi_init_dFp_nz_indices(jmi_t* jmi, int eval_alg, int independent_vars,
        int *mask, int* row, int* col);

/**
 * \brief This helper function computes the number of columns and the number of non-zero
 * elements in the Jacobian of the DAE initialization residual function \f$F_p\f$ given
 * a sparsity configuration.
 *
 * @param jmi A jmi_t struct.
 * @param eval_alg See ::jmi_dae_dF.
 * @param sparsity See ::jmi_dae_dF.
 * @param independent_vars See ::jmi_dae_dF.
 * @param mask See ::jmi_dae_dF.
 * @param dF_n_cols (Output) The number of columns of the resulting Jacobian.
 * @param dF_n_nz (Output) The number of non-zeros of the resulting Jacobian.
 *
 */
int jmi_init_dFp_dim(jmi_t* jmi, int eval_alg, int sparsity, int independent_vars, int *mask,
        int *dF_n_cols, int *dF_n_nz);

/**
 * \brief Evaluate the dependent parameters.
 *
 * @param jmi A jmi_t struct.
 * @return Error code.
 */
int jmi_init_eval_parameters(jmi_t* jmi);

/**
 * \brief Evaluate DAE event indicator residuals for the initialization system.
 *
 * The user sets the input variables by writing to
 * the vectors obtained from the functions ::jmi_get_dx, ::jmi_get_x etc.
 *
 * @param jmi A jmi_t struct.
 * @param res (Output) The event indicator residuals.
 * @return Error code.
 *
 */
int jmi_init_R0(jmi_t* jmi, jmi_real_t* res);

/* @} */

/**
 * \defgroup Misc Miscanellous
 * \brief Miscanellous functions.
 */
/* @{ */

/**
 * \brief Print a summary of the content of the jmi_t struct.
 *
 * @param jmi A jmi_t struct.
 */
void jmi_print_summary(jmi_t *jmi);

/**
 * \brief Linear interpolation in table.
 *
 * Linear interpolation is performed in a table consisting of an abscissa and
 * one or more ordinates. If the interpolation point resides outside of the
 * interval of the provided abscissa, then the initial or final ordinate
 * values, respectively, are returned.
 *
 * @param x The interpolation point.
 * @param z A matrix stored in column major format containing the abscissa,
 * stored in the first column, and the ordinates, stored in the following
 * columns.
 * @param n Number of points in the abscissa vector.
 * @param m Number of columns of z, i.e., the number of ordinate vectors plus
 * one for the abscissa.
 * @param y (Output) A vector of size m-1 containing the interpolated ordinate
 * values.
 */
void jmi_lin_interpolate(jmi_real_t x, jmi_real_t *z , int n ,int m,
        jmi_real_t *y);

/**
 * \brief Check if there is support for CAD derivatives or not.
 *
 * If the return value is 1 then there is support for CAD derivatives,
 * if return value is 0 there is no CAD support.
 *
 * @param jmi A jmi_t struct.
 * 
 * @return 1 for CAD support, 0 if no CAD support.
 */
int jmi_with_cad_derivatives(jmi_t* jmi);

/**
 * \brief Set start values for all non alias variables.
 *  
 * @param jmi A jmi_t struct.
 */
int jmi_set_start_values(jmi_t *jmi);

#endif
